package com.mxw.service;


import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectResult;
import com.mxw.entity.Resource;
import com.mxw.mapper.ResourceMapper;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class AWebSpiderService {
    private static final Logger logger = LoggerFactory.getLogger(AWebSpiderService.class);

    @Autowired
    private ResourceMapper internetSoftwareMapper;

    private final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .build();

    private final Random random = new Random();

    // 随机延迟5-15秒
    private void randomDelay() {
        try {
            int delay = 5000 + random.nextInt(10000); // 5000-15000ms
            logger.info("等待 {} 秒...", delay / 1000);
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    // 随机延迟2-5秒
    private void shortDelay() {
        try {
            int delay = 2000 + random.nextInt(3000); // 2000-5000ms
            logger.info("等待 {} 秒...", delay / 1000);
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    private String uploadToOSS(InputStream inputStream, String fileName) {
        // OSS配置信息
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        String accessKeyId = "LTAI5t7becHMxj1ZDyBkZb9i";
        String accessKeySecret = "UsrLcrGtWfrlszBHIdksfg9i5DRq92";
        String bucketName = "milkcode";

        // 创建OSS实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 上传文件流
            String ossFileName = "containerdata/" + fileName;
            ossClient.putObject(bucketName, ossFileName, inputStream);

            // 生成访问URL
            String url = "https://" + bucketName + "." + endpoint + "/" + ossFileName;
            logger.info("图片已上传到OSS: {}", url);
            return url;
        } catch (Exception e) {
            logger.error("上传OSS失败: {}", fileName);
            e.printStackTrace();
            return null;
        } finally {
            // 关闭OSSClient
            ossClient.shutdown();
        }
    }

    private String downloadAndUploadImage(String imageUrl, String fileName) {
        try {
            // 创建请求
            Request request = new Request.Builder()
                    .url(imageUrl)
                    .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
                    .header("Accept", "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8")
                    .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
                    .header("Referer", "https://www.ahhhhfs.com/")
                    .header("sec-ch-ua", "\"Google Chrome\";v=\"91\", \"Chromium\";v=\"91\"")
                    .header("sec-ch-ua-mobile", "?0")
                    .header("sec-ch-ua-platform", "\"Windows\"")
                    .header("Sec-Fetch-Dest", "image")
                    .header("Sec-Fetch-Mode", "no-cors")
                    .header("Sec-Fetch-Site", "same-origin")
                    .build();

            // 执行请求
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("下载失败: " + response.code());
                }

                // 获取响应流并上传到OSS
                try (InputStream inputStream = response.body().byteStream()) {
                    return uploadToOSS(inputStream, fileName);
                }
            }
        } catch (Exception e) {
            logger.error("下载图片失败: {}", imageUrl, e);
            return null;
        }
    }

    private Resource testCrawlWayToAGIInfo(String infoURl, String title, String coverUrl) throws IOException {
        Resource resource = new Resource();
        Document articleDoc = Jsoup.connect(infoURl).get();

        // 获取article元素
        Element article = articleDoc.select("article.post-content").first();
        if (article != null) {
            // 设置标题和封面
            resource.setTitle(title);
            Set<String> picUrls = new HashSet<>();

            if (coverUrl != null) {
                String fileName = title + "1.jpg";
                String ossUrl = downloadAndUploadImage(coverUrl, fileName);
                if (ossUrl != null) {
                    resource.setCoverUrl(ossUrl);
                    picUrls.add(ossUrl);
                }
            }

            // 获取文章内容
            StringBuilder infoText = new StringBuilder();
            Elements paragraphs = article.select("p");
            for (Element p : paragraphs) {
                String text = p.text();
                // 过滤不需要的内容
                if (!text.contains("👍") &&
                        !text.contains("下载地址") &&
                        !text.contains("https") &&
                        !text.contains("本文链接") &&
                        !text.contains("相关") &&
                        !text.contains("版权")) {
                    // 替换特定文本
                    text = text.replace("A姐", "小编");
                    infoText.append(text).append("\n");
                }
            }
            resource.setContent(infoText.toString());

            // 获取所有链接
            List<String> infoHref = new ArrayList<>();
            Elements links = article.select("a");
            boolean foundDetailImage = false; // 标记是否已找到详情图片

            for (Element link : links) {
                String href = link.attr("href");
                if (href != null && !href.isEmpty()) {
                    if (!href.contains("ahhhhfs") && href.startsWith("http")) {
                        infoHref.add(href);
                        // 设置资源链接
                        if (resource.getResourceUrl() == null) {
                            resource.setResourceUrl(href);
                        }
                    }

                    //下载并上传图片到OSS，只处理第一张图片
                    if (!foundDetailImage && href.endsWith(".jpg")) {
                        try {
                            String fileName = title + "2.jpg";

                            // 下载图片
                            URL url = new URL(href);
                            URLConnection conn = url.openConnection();
                            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

                            // 直接上传到OSS
                            String ossUrl = uploadToOSS(conn.getInputStream(), fileName);
                            if (ossUrl != null) {
                                picUrls.add(ossUrl);
                                foundDetailImage = true; // 标记已找到详情图片
                            }

                            // 等待2秒
                            Thread.sleep(2000);

                        } catch (Exception e) {
                            logger.error("处理图片失败: {}", href, e);
                        }
                    }
                }
            }

            // 将图片URL集合转换为JSON字符串
            if (!picUrls.isEmpty()) {
                resource.setPicUrl(JSON.toJSONString(picUrls));
            }

            // 设置其他属性
            resource.setAuthor("小编");
            resource.setViewCount(0L);
            resource.setLikeCount(0L);
            resource.setCreateTime(new Date());
            resource.setModifyTime(new Date());

            return resource;
        } else {
            logger.warn("未找到文章内容");
            return null;
        }
    }

    public void spider(int pageParam) throws IOException {
        String baseUrl = "https://www.ahhhhfs.com/page/1/";
        int startPage = pageParam > 0 ? pageParam : 6;
        int endPage = 1;    // 爬取到第1页
        List<Resource> allResources = new ArrayList<>();
        for (int page = startPage; page >= endPage; page--) {
            String pageUrl = baseUrl.replace("/1", "/" + page);
            logger.info("正在爬取第 {} 页: {}", page, pageUrl);

            try {
                // 页面间随机延迟
                randomDelay();

                Document doc = Jsoup.connect(pageUrl)
                        .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
                        .timeout(10000)
                        .get();

                Elements posts = doc.select("div.posts-warp.row.row-cols-1.row-cols-md-2.g-2.g-md-3.g-lg-4");
                if (posts.isEmpty()) {
                    logger.info("页面 {} 没有找到文章列表，可能已到达最后一页", page);
                    continue;
                }

                List<Resource> pageResources = new ArrayList<>();
                for (Element post : posts) {
                    Elements articles = post.select("article.post-item.item-list");
                    for (Element article : articles) {
                        String link = article.select("h2.entry-title a").attr("href");
                        String title = article.select("h2.entry-title a").text();
                        logger.debug("文章链接: {}", link);
                        logger.debug("文章标题: {}", title);

                        // 获取封面信息
                        String coverUrl = null;
                        Element coverElement = article.select("div.entry-media.ratio.ratio-3x2.col-auto").first();
                        if (coverElement != null) {
                            coverUrl = coverElement.select("a.media-img").attr("data-bg");
                            logger.debug("封面URL: {}", coverUrl);
                        }

                        // 文章间短延迟
                        shortDelay();

                        // 爬取文章详情并封装为Resource对象
                        Resource resource = testCrawlWayToAGIInfo(link, title, coverUrl);
                        if (resource != null) {
                            try {
                                // 尝试插入新记录
                                internetSoftwareMapper.insert(resource);
                            } catch (Exception e) {
                                // 如果插入失败（标题重复），则更新记录
                                internetSoftwareMapper.updateById(resource);
                            }
                            pageResources.add(resource);
                        }
                    }
                }

                allResources.addAll(pageResources);
                logger.info("第 {} 页爬取完成，获取到 {} 篇文章", page, pageResources.size());

            } catch (Exception e) {
                logger.error("爬取第 {} 页时发生错误: {}", page, e.getMessage(), e);
                e.printStackTrace();
                // 如果发生错误，继续爬取下一页
                continue;
            }
        }
        // 打印爬取结果
        logger.info("\n爬取完成，总共获取到 {} 篇文章", allResources.size());
        for (Resource resource : allResources) {
            logger.debug("标题: {}", resource.getTitle());
            logger.debug("内容: {}", resource.getContent());
            logger.debug("资源链接: {}", resource.getResourceUrl());
            logger.debug("封面图: {}", resource.getCoverUrl());
            logger.debug("图片: {}", resource.getPicUrl());
            logger.debug("-------------------");
        }
    }
}
